package com.demo.controller;

import java.awt.Image;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import com.demo.bean.Ret;
import com.demo.service.BFileService;
import com.demo.util.FileExportUtils;
import com.demo.util.FileUpRetn;
import com.demo.util.ImageUtils;
import com.demo.util.JSONUtils;
import com.demo.util.ProperityUtil;
import com.demo.util.ResponseUtils;
import com.mdx.mobile.commons.verfy.Md5;

@Controller
public class FileController extends CoreAdminController{
	@Autowired
	BFileService fileService;
	@Autowired
	ProperityUtil properity;
	
	private Logger logger = Logger.getLogger(FileController.class);
	
//	@RequestMapping("/fileUpload")
//	public void fileUpload(String dir,HttpServletRequest request,HttpServletResponse response)
//			throws Exception {
//		// 文件保存目录路径
//		String fileId = "";
//		String savePath = properity.getFile_dir();
//		String callback = request.getParameter("callback");
//		Collection<Part> parts = request.getParts();
//		
//			
//		for (Part part : parts) {
//			String fileName = part.getName();
//			String md5 = Md5.md5(part.getInputStream());
//			List<Map<String, Object>> lf = fileService.selectByFileMd5(md5);
//			if(lf.size()>0){
//				if(!StringUtils.isBlank(callback)){
//					ResponseUtils.render(response, "<script>parent."+callback+"('"+lf.get(0).get("file_id")+"')</script>","text/html;charset=UTF-8");
//					return;
//				}
//				if ("image".equals(dir)) {
//					ResponseUtils.renderJson(response, new FileUpRetn(0, "download.do?id=" +lf.get(0).get("file_id"), fileName, new Long(lf.get(0).get("file_size").toString())));
//					return;
//				}
//				ResponseUtils.renderJson(response, new FileUpRetn(0, lf.get(0).get("file_id").toString(), fileName, new Long(lf.get(0).get("file_size").toString())));
//				return;
//			}
//			long itemsize=part.getSize();
//			// 检查文件大小
//			if (itemsize >Long.parseLong(properity.getFile_maxsize())) {
//				if(!StringUtils.isBlank(callback)){
//					ResponseUtils.renderText(response, "<script>parent."+callback+"(1)</script>");
//					return;
//				}
//				ResponseUtils.renderJson(response, getError("上传文件大小超过限制。"));
//				return;
//			}
//			// 检查扩展名
//			String fileExt = fileName.substring(
//					fileName.lastIndexOf(".") + 1).toLowerCase();
//			String newFileName = UUID.randomUUID().toString()
//					.replace("-", "");
//			String minetype = FileExportUtils.getMine(fileName);
//			
//
//			if(fileName.endsWith(".apk")){
//				minetype = "application/vnd.android.package-archive";
//			}else if(fileName.endsWith(".ipa")){
//				minetype = "application/iphone-package-archive";
//			}
//			
//			
//			try {
//				Calendar cal=Calendar.getInstance();
//				String realdir = cal.get(Calendar.YEAR)+"-"+(cal.get(Calendar.MONTH)+1)+"-"+(cal.get(Calendar.DAY_OF_MONTH))+"/"+minetype.replace("-", "")
//						.replace("/", "_");
//				File f = new File(savePath, realdir);
//				if (!f.isDirectory()) {
//					f.mkdirs();
//				}
//				File uploadedFile = new File(f.getPath(), newFileName + "."+fileExt);
//				FileOutputStream fos = new FileOutputStream(uploadedFile);
//				fos.write(StreamUtils.copyToByteArray(part.getInputStream()));
//				fos.close();
//				com.demo.domain.File ac = new com.demo.domain.File();
//				ac.setFileId(StringUtil.getUUID());
//				ac.setFileId(newFileName);
//				ac.setFileMinitype(minetype);
//				ac.setFilePath(realdir + "/" + newFileName + "."+fileExt);
//				ac.setFileState(1);
//				ac.setFileSize(BigDecimal.valueOf(itemsize));
//				ac.setFileMd5(md5);
//				ac.setFileCreatetime(new Date());
//				ac.setFileName(fileName);
////				ac.setFileBelong(belong);
//				
//				if(FileExportUtils.isImage(fileName)){
//					BufferedImage bufferedImage = ImageIO.read(uploadedFile);   
//					int width = bufferedImage.getWidth();   
//					int height = bufferedImage.getHeight();  
//					ac.setFileCreater(width+"x"+height);
//				}
//				fileService.save(ac);
//			} catch (Exception e) {
//				e.printStackTrace();
//				if(!StringUtils.isBlank(callback)){
//					ResponseUtils.render(response, "<script>parent."+callback+"(2)</script>","text/html;charset=UTF-8");
//					return;
//				}
//				ResponseUtils.renderJson(response, getError("上传文件失败。"));
//				return;
//			}
//			if(!StringUtils.isBlank(callback)){
//				ResponseUtils.render(response, "<script>parent."+callback+"('"+newFileName+"')</script>","text/html;charset=UTF-8");
//				return;
//				
//			}
//			if ("image".equals(dir)) {
//				newFileName = "download.do?id="+newFileName;
//			}
//			ResponseUtils.renderJson(response, new FileUpRetn(0, newFileName, fileName, itemsize));
//		}
//		
//		
//		Map<String, Object> msg = new HashMap<String, Object>();
//		msg.put("error", 1);
//		msg.put("message", "没有发现文件域");
//		if(!StringUtils.isBlank(callback)){
//			ResponseUtils.render(response, "<script>parent."+callback+"(3)</script>","text/html;charset=UTF-8");
//			return;
//		}
//		ResponseUtils.renderJson(response, msg);
//		return;
//	}
	
	@RequestMapping("/fileUpload")
	public void fileUpload(HttpServletRequest request, HttpServletResponse response,HttpSession session,String dir)
			throws Exception {
		// 文件保存目录路径
		String savePath = properity.getFile_dir();
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;    
        Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();   
		
		if (!ServletFileUpload.isMultipartContent(request)) {
			ResponseUtils.renderJson(response, getError("请选择文件"));
			return;
		}

		// 检查目录
		File uploadDir = new File(savePath);
		if (!uploadDir.isDirectory()) {
			uploadDir.mkdirs();
		}
		 
		String callback = request.getParameter("callback");
		while (fileMap.keySet().iterator().hasNext()) {
			MultipartFile item =   fileMap.get(fileMap.keySet().iterator().next());
			String fileName = item.getOriginalFilename();
			String md5 = Md5.md5(item.getInputStream());
			List<Map<String, Object>> lf = fileService.selectByFileMd5(md5);
			if (lf.size() > 0) {
				if(!StringUtils.isBlank(callback)){
					ResponseUtils.render(response, "<script>parent."+callback+"('"+lf.get(0).get("file_id")+"')</script>","text/html;charset=UTF-8");
					return;
				}
				if ("image".equals(dir)) {
					ResponseUtils.renderJson(response, new FileUpRetn(0, "download.do?id=" +lf.get(0).get("file_id"), fileName, new Long(lf.get(0).get("file_size").toString())));
					return;
				}
				ResponseUtils.renderJson(response, new FileUpRetn(0, lf.get(0).get("file_id").toString(), fileName, new Long(lf.get(0).get("file_size").toString())));
				return;
			}
			long itemsize=item.getSize();

			// 检查文件大小
			if (itemsize >Long.parseLong(properity.getFile_maxsize())) {
				if(!StringUtils.isBlank(callback)){
					ResponseUtils.renderText(response, "<script>parent."+callback+"(1)</script>");
					return;
				}
				ResponseUtils.renderJson(response, getError("上传文件大小超过限制。"));
				return;
			}
			
			// 检查扩展名
			String fileExt = fileName.substring(
					fileName.lastIndexOf(".") + 1).toLowerCase();
			String newFileName = UUID.randomUUID().toString()
					.replace("-", "");
			String minetype = FileExportUtils.getMine(fileName);
			
			if(fileName.endsWith(".apk")){
				minetype = "application/vnd.android.package-archive";
			}else if(fileName.endsWith(".ipa")){
				minetype = "application/iphone-package-archive";
			}
			
			try {
				Calendar cal=Calendar.getInstance();
				String realdir = cal.get(Calendar.YEAR)+"-"+(cal.get(Calendar.MONTH)+1)+"-"+(cal.get(Calendar.DAY_OF_MONTH))+"/"+minetype.replace("-", "")
						.replace("/", "_");
				File f = new File(savePath, realdir);
				if (!f.isDirectory()) {
					f.mkdirs();
				}
				File uploadedFile = new File(f.getPath(), newFileName + "."
						+ fileExt);
				FileOutputStream fos = new FileOutputStream(uploadedFile);
				fos.write(item.getBytes());
				fos.close();
				com.demo.domain.File ac = new com.demo.domain.File();
				ac.setFileId(newFileName);
				ac.setFileMinitype(minetype);
				ac.setFilePath(realdir + "/" + newFileName + "." + fileExt);
				ac.setFileState(1);
				ac.setFileSize(BigDecimal.valueOf(itemsize));
				ac.setFileMd5(md5);
				ac.setFileCreatetime(new Date());
				ac.setFileName(fileName);
				//ac.setFileBelong(getAppId(session));
				
				if(FileExportUtils.isImage(fileName)){
					BufferedImage bufferedImage = ImageIO.read(uploadedFile);   
					int width = bufferedImage.getWidth();   
					int height = bufferedImage.getHeight();  
					ac.setFileCreater(width+"x"+height);
				}
				
				fileService.save(ac);
			} catch (Exception e) {
				e.printStackTrace();
				if(!StringUtils.isBlank(callback)){
					ResponseUtils.render(response, "<script>parent."+callback+"(2)</script>","text/html;charset=UTF-8");
					return;
				}
				ResponseUtils.renderJson(response, getError("上传文件失败。"));
				return;
			}
			if(!StringUtils.isBlank(callback)){
				ResponseUtils.render(response, "<script>parent."+callback+"('"+newFileName+"')</script>","text/html;charset=UTF-8");
				return;
				
			}
			if ("image".equals(dir)) {
				newFileName = "/download.do?id="+newFileName;
			}
			ResponseUtils.renderJson(response, new FileUpRetn(0, newFileName, fileName, itemsize));
			return; 
		}
		Map<String, Object> msg = new HashMap<String, Object>();
		msg.put("error", 1);
		msg.put("message", "没有发现文件域");
		if(!StringUtils.isBlank(callback)){
			ResponseUtils.render(response, "<script>parent."+callback+"(3)</script>","text/html;charset=UTF-8");
			return;
		}
		ResponseUtils.renderJson(response, msg);
		return;
	}
	
	 
	
	@RequestMapping("/download/{id}")
	public void downloadFile(HttpServletResponse resp,
			HttpServletResponse response, @PathVariable("id") String id,
			@RequestParam(value = "w", required = false) String width,
			@RequestParam(value = "h", required = false) String height)
			throws Exception {
		downloadFile(id, response, width,height, null);
	}
	
	@RequestMapping("/download")
	public void downloadFile(String id,HttpServletResponse resp,
			@RequestParam(value = "w", required = false) String w,
			@RequestParam(value = "h", required = false) String h,String type) throws Exception{
		if(id!=null){
			com.demo.domain.File item = fileService.selectByPrimaryKey(id);
			if (item == null) {
				logger.error("文件不存在;id="+id);
				return;
			} else {
				File filepath = new File(properity.getFile_dir() + "/"+item.getFilePath());
				int width = 0, height = 0;
				if (w != null && w.length() > 0) {
					width = Integer.valueOf(w);
				}
				if (h != null && h.length() > 0) {
					height = Integer.valueOf(h);
				}
				if (width != 0 && item.getFileMinitype().startsWith("image")) {
					// 检查目录
					File tempDirectory= new File(properity.getFile_dir() + "/temp/");
					if (!tempDirectory.isDirectory()) {
						tempDirectory.mkdirs();
					}
					
					String tf =properity.getFile_dir() + "/temp/" +  item.getFileMd5() +"_"+ width + "x" + height + ".jpg";
					File tempfile = new File(tf);
					if (tempfile.exists()) {
						filepath = tempfile;
					} else {
						if (height == 0) {
							BufferedImage buf=ImageIO.read(filepath);
							if (buf.getWidth() > width) {
								ImageUtils.Compress(filepath, tempfile, width);
								filepath = tempfile;
							}
						} else {
							ImageUtils.Compress(filepath, tempfile, width, height);
							filepath = tempfile;
						}
					}
				}
				
				if(item.getFileMinitype().startsWith("image")){
					type = "inline";
				}
				
				resp.setContentType(item.getFileMinitype() + "; charset=utf-8");
				if (!filepath.exists()) {
					logger.error("文件没找到;id="+id);
					return;
				}
				FileExportUtils.download(resp, item.getFileName(), item.getFileMinitype(), filepath,type);
			}
		}
	}
	@RequestMapping("/replaceImg")
	@ResponseBody
	public String cutImg(String imgId,Integer startX,Integer startY,Integer width,Integer height,Integer currentW,Integer currentH,HttpServletRequest request) throws Exception{
		
		com.demo.domain.File bfile = fileService.selectByPrimaryKey(imgId);
		String src="";
		String id ="";
		if(bfile==null)
			src=request.getContextPath()+"/"+imgId;
		else
			src=properity.getFile_dir()+ "/"+bfile.getFilePath();
		int n =bfile.getFilePath().lastIndexOf(".");
		String ext =bfile.getFilePath().substring(n+1);
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		ByteArrayOutputStream baos1 = new ByteArrayOutputStream();
		try {
			//图片压缩
			zoomImage(src, currentW, currentH, ext, baos);
			byte[] newImg = ImageUtils.cut(baos.toByteArray(), ext, startX, startY, width, height);
			id = fileService.uploadFile(newImg, bfile.getFileName(), bfile.getFileBelong());
		}catch(Exception e){
			e.printStackTrace();
			return JSONUtils.serialize(new Ret(0));
		}finally{
			if(baos!=null){
				baos.close();
			}
			if(baos1!=null){
				baos1.close();
			}
		}
		return JSONUtils.serialize(new Ret(1, id));
	}
	
    /* 
     * 图片缩放 
     */  
    public static void zoomImage(String src,int w,int h,String ext,ByteArrayOutputStream baos) throws Exception {  
        double wr=0,hr=0;  
        File srcFile = new File(src);  
        BufferedImage bufImg = ImageIO.read(srcFile);  
        Image itemp = bufImg.getScaledInstance(w, h, Image.SCALE_SMOOTH);
        wr=w*1.0 / bufImg.getWidth();  
        hr=h*1.0 / bufImg.getHeight();  
        AffineTransformOp ato = new AffineTransformOp(AffineTransform.getScaleInstance(wr, hr), null);  
        itemp = ato.filter(bufImg, null);  
        try {  
            ImageIO.write((BufferedImage) itemp,ext, baos);  
        } catch (Exception ex) {  
            ex.printStackTrace();  
        }  
          
    }  
	
	private FileUpRetn getError(String message) {
		return new FileUpRetn(1, message);
	}
	
}
